package com.baijiayun.live.ui.chat

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.drawable.ColorDrawable
import androidx.core.content.ContextCompat
import android.text.SpannableStringBuilder
import android.text.util.Linkify
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewTreeObserver
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.baijiahulian.common.utils.StringUtils
import com.baijiayun.glide.Glide
import com.baijiayun.glide.request.RequestOptions
import com.baijiayun.live.ui.R
import com.baijiayun.liveuibase.utils.DisplayUtils
import com.baijiayun.liveuibase.utils.ThemeDataUtil
import kotlin.math.abs

@SuppressLint("ViewConstructor")
/**
 * 置顶 item
 */
class StickyItemLinearLayout(context: Context, val index: Int) : LinearLayout(context), ViewTreeObserver.OnGlobalLayoutListener {
    private var tvUserName: TextView
    private var tvContent: TextView
    private var ivImage: ImageView
    private var tvCancelSticky: TextView
    private var tvCount: TextView
    private var stickyItemListener: StickyItemListener? = null

    private val detailPrefix = "\u3000\u3000"
    private lateinit var detailContent: String
    private lateinit var imgUrl: String
    private var isImage = false
    private var count: Int = 0
    private var canCancel = false

    private val failedDrawable = ColorDrawable(ContextCompat.getColor(context, R.color.live_half_transparent))

    var contentView: View = LayoutInflater.from(context).inflate(R.layout.bjy_chat_stick_item_layout, null)

    init {
        tvUserName = contentView.findViewById(R.id.fragment_chat_sticky_user)
        tvCount = contentView.findViewById(R.id.fragment_chat_sticky_count)
        tvContent = contentView.findViewById(R.id.fragment_chat_sticky_content)
        ivImage = contentView.findViewById(R.id.fragment_chat_sticky_image)
        tvContent.setOnClickListener {
            if (stickyItemListener != null) stickyItemListener!!.onContentClick()
        }
        ivImage.setOnClickListener {
            if (stickyItemListener != null) stickyItemListener!!.onContentClick()
        }
        tvCancelSticky = contentView.findViewById(R.id.fragment_chat_cancel_sticky)
        tvCancelSticky.setOnClickListener {
            if (stickyItemListener != null) stickyItemListener!!.onCancelSticky()
        }

        initCancelStickyColor()
    }

    @SuppressLint("ClickableViewAccessibility")
    private fun initCancelStickyColor() {
        // region 取消置顶长按变色
        // 移动偏移触发距离
        val focusUnitOffset = 50
        val normalColor = ThemeDataUtil.getColorFromThemeConfigByAttrId(context, R.attr.base_theme_window_assistant_text_color)
        val onLongLickColor = ContextCompat.getColor(context, R.color.live_pad_red)

        var hasLongClick = false
        var originX = 0f
        var originY = 0f
        tvCancelSticky.setOnLongClickListener {
            // 长按切换
            hasLongClick = true
            tvCancelSticky.setTextColor(onLongLickColor)
            false
        }
        // 监测按下后移动
        tvCancelSticky.setOnTouchListener(object : OnTouchListener {
            override fun onTouch(v: View?, event: MotionEvent?): Boolean {
                if (event == null) {
                    return false
                }
                if (event.action == MotionEvent.ACTION_DOWN) {
                    hasLongClick = false
                    originX = event.x
                    originY = event.y
                } else {
                    if (abs(event.x - originX) > focusUnitOffset
                            || abs(event.y - originY) > focusUnitOffset
                            || event.action == MotionEvent.ACTION_UP) {
                        tvCancelSticky.setTextColor(normalColor)
                    }
                    return hasLongClick
                }
                return false
            }
        })
        // endregion
    }

    fun initValue(userName: String, content: String, isImg: Boolean) = apply {
        tvUserName.text = userName
        if(!isImg) {
            tvContent.text = stickyItemListener?.onGetMixText(content,tvContent)
            tvContent.visibility = View.VISIBLE
            detailContent = content
        } else {
            detailContent = context.getString(R.string.live_chat_sticky_click_watch_pic)
            tvContent.text = detailContent
            imgUrl = content
        }
        this.isImage = isImg
        updateContentLinkEnable(true)
    }

    fun initListener(stickyItemListener: StickyItemListener) = apply {
        this.stickyItemListener = stickyItemListener
    }

    fun setCancelStickyVisibility(visible: Boolean) = apply {
        canCancel = visible
        tvCancelSticky.visibility = if (visible) View.VISIBLE else View.GONE
    }

    fun setStickyCount(count: Int) {
        this.count = count
        tvCount.visibility = if (count > 1) View.VISIBLE else View.GONE
        tvCount.text = StringUtils.toString(count)
    }

    /**
     * 是否启用文本内链接
     */
    private fun updateContentLinkEnable(enable: Boolean) {
        if (isImage) {
            return
        }
        if (enable) {
            Linkify.addLinks(tvContent, Linkify.WEB_URLS or Linkify.EMAIL_ADDRESSES)
        } else {
            tvContent.autoLinkMask = 0
        }
    }

    var haveNotLoadImage = true

    /**
     * true，全部展示 、 false，仅第一个缩略，其他 gone
     */
    fun updateLayoutForDetail(isDetail: Boolean) {
        contentView.visibility = if (!isDetail && index != 0) View.GONE else View.VISIBLE
        if (isImage) {
            tvContent.visibility = if (isDetail) View.GONE else View.VISIBLE
            ivImage.visibility = if (isDetail) View.VISIBLE else View.GONE

            if (isDetail && haveNotLoadImage) {
                ivImage.post {
                    val requestOptions = RequestOptions()
                            .placeholder(failedDrawable)
                            .error(failedDrawable)
                    Glide.with(context).asBitmap()
                            .load(imgUrl)
                            .apply(requestOptions)
                            .into(ivImage)
                }
                haveNotLoadImage = false
            }
        }
        if (index != 0) {
            return
        }
        // region 视图及背景属性更新
        tvUserName.visibility = if (isDetail) View.VISIBLE else View.GONE
        tvCancelSticky.visibility = if (isDetail && canCancel) View.VISIBLE else View.GONE

        tvContent.text = stickyItemListener?.onGetMixText(if (isDetail) detailContent else detailPrefix + detailContent,tvContent)
        tvContent.background = if (isDetail)
            ContextCompat.getDrawable(context, R.drawable.item_pad_chat_text_gray_bg)
        else null
        val contentPadding = DisplayUtils.dip2px(context, if (isDetail) 8f else 2f)
        tvContent.setPadding(contentPadding, contentPadding, contentPadding, contentPadding)
        // endregion

        // tvContent 增加 GlobalLayoutListener ，控制缩略
        if (!isDetail) {
            tvContent.viewTreeObserver.addOnGlobalLayoutListener(this)
            setStickyCount(count)
        } else {
            tvCount.visibility = View.GONE
        }
        updateContentLinkEnable(isDetail)
    }

    override fun onDetachedFromWindow() {
        tvContent.viewTreeObserver.removeOnGlobalLayoutListener(this)
        super.onDetachedFromWindow()
    }

    interface StickyItemListener {
        fun onContentClick()
        fun onCancelSticky()
        fun onGetMixText(src: CharSequence, textView: TextView): SpannableStringBuilder
    }

    private val maxLine = 2

    override fun onGlobalLayout() {
        if (stickyItemListener != null) {
            val ssb: SpannableStringBuilder = if (tvContent.lineCount > maxLine) {
                // 显示缩略
                var showText = tvContent.text
                val lineEndIndex = tvContent.layout.getLineEnd(maxLine - 1)
                showText = showText.subSequence(0,
                        lineEndIndex - if (showText[lineEndIndex - 1] == '\n') 1 else 3)

                stickyItemListener!!.onGetMixText("$showText...", tvContent)
            } else {
                stickyItemListener!!.onGetMixText(tvContent.text, tvContent)
            }
            tvContent.text = ssb
        }
        tvContent.viewTreeObserver.removeOnGlobalLayoutListener(this)
    }
}